/*
 * @Author: xiaosihan 
 * @Date: 2022-03-20 14:48:33 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2022-09-30 00:12:28
 */

import { throttle } from "lodash";
import { Event, EventDispatcher, EventListener, Vector3 } from "three";
import { generateUUID } from "three/src/math/MathUtils";


/**
 * 键盘 使用 ↑↓←→ 控制 x z 方向, 小键盘 1 0 控制 y 方向
 *
 * @class KeyContorls
 * @extends {EventDispatcher}
 */
class KeyContorls extends EventDispatcher {

    constructor() {
        super();
        this.addEvent();
    }

    uuid = generateUUID();

    direction = new Vector3(0, 0, 0);

    // 添加事件需要由外部实现
    add(e: any) {
        this.dispatchEvent({ ...e, type: "add" } as never);
    }

    // 删除事件
    delete(e: any) {
        this.dispatchEvent({ ...e, type: "delete" } as never);
    }

    // 回车按钮
    enter(e: any) {
        this.dispatchEvent({ ...e, type: "enter" } as never);
    }

    keyDown = (e: any) => {

        switch (e.keyCode) {

            case 46: // 删除按钮
                this.delete(e);
                return;

            case 13: // 回车按钮
                this.enter(e);
                return;

            case 97: // 小键盘1
                this.direction.set(0, 1, 0);
                break;
            case 96: // 小键盘0
                this.direction.set(0, -1, 0);
                break;

            case 35: // 
                this.direction.set(0, 0.001, 0);
                break;
            case 45:
                this.direction.set(0, -0.001, 0);
                break;

            case 38: // 前
                this.direction.set(0, 0, -1);
                break;
            case 37: // 后
                this.direction.set(-1, 0, 0);
                break;
            case 40: // 左
                this.direction.set(0, 0, 1);
                break;
            case 39: // 右
                this.direction.set(1, 0, 0);
                break;

            default:
                return;
        }

        if (e.shiftKey) {
            this.direction.multiplyScalar(0.001);
        }

        if (e.ctrlKey) {
            this.direction.multiplyScalar(0.1);
        }

        this.dispatchEvent({
            type: "change",
            direction: this.direction
        } as never);

    }

    _listeners?: { [key: string]: Array<any> };

    // 节流 删除事件监听
    removeEvent = throttle((type: string) => {
        this._listeners = undefined;
    }, 1000, { trailing: false });

    addEventListener<T extends string>(type: T, listener: EventListener<{}, T, this>): void {
        this.removeEvent(type);
        super.addEventListener(type, listener);
    }

    addEvent() {
        document.addEventListener("keydown", this.keyDown);
    }

    dispose() {
        document.removeEventListener("keydown", this.keyDown);
    }

}

const keyContorls = new KeyContorls();

export default keyContorls;
